require_relative 'lib'
require_relative 'macrofunc'

$min_vitality = 10
$max_vitality = 65535

$is_reviving = false
$is_reviving_buffer = false

class Scheduler
	def check_yammy_slots
		i_slots = [0, 1]
		i_slots.push [$registers[0][:slot].field] if (0..255).include? $registers[0][:slot].field
		slot_to_steal = i_slots.map { |i| $enemy_slots[i] } .find { |slot| ($prefered.reverse.take(30)).include?(slot.field) }
		if slot_to_steal && ($my_slots[slot_to_steal.field].dead? || !$enemy_slots[slot_to_steal.field].dead?)
			thief = $my_slots[2]
			copy thief, slot_to_steal.index
		end
	end
	def check_for_quick_revive
		return if $is_reviving
		
		slot = $registers.find { |r| r[:slot].dead? }
		slot = slot[:slot] if slot
		if !slot
			r = $registers.find { |r| r[:slot].field.respond_to?("<") && $my_slots[r[:slot].field].dead? }
			slot = $my_slots[r[:slot].field] if r
		end
		
		if slot
			#p "found reveive!"
			$is_reviving = true
			#puts $command_queue.size
			priest = $my_slots[find_vacant]

			if(!$command_queue.empty?)
				$commands_backup = $command_queue
				$is_reviving_buffer = true
				$command_queue = CommandQueue.new
			end


			revive(priest, slot.index)
			#commands.each { |c| $command_queue.push c }

		end
	end

  def recover_from_revive
    $command_queue = $commands_backup
    $is_reviving = false
    $is_reviving_buffer = false
  end


	
	def kill target
		# search for ammo
		ammo_needed = (target.vitality + 1) * 10 / 9
		
		# search for the best ammo slot
		ammo = $my_slots.find_all{|x| x.vitality > ammo_needed}.max {|a, b| a.vitality - ammo_needed <=> b.vitality - ammo_needed }
		if ammo == nil
			ammo = $my_slots.max {|x, y| x.vitality <=> y.vitality}
		end
		
		# pick a canon
		canon = $my_slots[find_vacant]
		
		# fire
		attack(canon, ammo.index, 255-target.index, ammo_needed >= ammo.vitality ? ammo.vitality - 5 : ammo_needed)
	end
	


	def t2 x
		i = 1
		while i * 2 < x
			i *= 2
		end
		i

		#x & 0xFF00
		x
	end

	def calc_vitality_boost from, to
		power = t2([from.vitality - $min_vitality, ($max_vitality - to.vitality) * 10 / 11].min)

		([to.vitality + power * 11 / 10, $max_vitality].min - to.vitality - (to == from ? from.vitality : 0)) * 100000 + to.vitality
	end

	def choose_and_heal
		donor = $my_slots.max {|x,y| x.vitality <=> y.vitality}

		patient = $my_slots.find_all{|x| !x.dead?}.max {|x,y| calc_vitality_boost(donor, x) <=> calc_vitality_boost(donor, y)}
		power = t2([donor.vitality - $min_vitality, ($max_vitality - patient.vitality) * 10 / 11].min)
		
		canon = $my_slots[ find_vacant || 0]
		
		puts "#{donor} #{patient}"
		
		help(canon, donor.index, patient.index, power) if power > 0
	end

=begin	
	def heal slot, target_vitality
		#search for source
		best_source = $my_slots.
			find_all {|s| s != slot }.
			max { |a, b| a.vitality <=> b.vitality }
		
		vitality_needed = target.vitality - slot.vitality + 1 # we want to stay alife
		
		vitality_to_spend = vitality_needed * 10 / 11
		
		if (best_surce.vitality > vitality_to_spend)
			# pick a slot for help function
			helper = $my_slots[find_vacant]
			help(helper, best_source, slot, vitality_to_spend)
		end
	end
=end

	def choose_and_kill
		target = $enemy_slots.reverse.find { |x| !x.dead? }
		kill target if target
	end
	
	def choose_and_kill_register
		target = $enemy_slots.find { |x| !x.dead? }
		if (target && target.index < 3)
			kill target
		else
			choose_and_kill
		end
		
	end

end

$scheduler = Scheduler.new